home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
language
/
pcl_src.zoo
/
xerox-patches.lsp
< prev
Wrap
Lisp/Scheme
|
1992-07-09
|
10KB
|
249 lines
;;; -*- Mode: Lisp; Package: XCL-USER; Base: 10.; Syntax: Common-Lisp -*-
;;;
;;; *************************************************************************
;;; Copyright (c) 1985, 1986, 1987, 1988, 1989, 1990 Xerox Corporation.
;;; All rights reserved.
;;;
;;; Use and copying of this software and preparation of derivative works
;;; based upon this software are permitted. Any distribution of this
;;; software or derivative works must comply with all applicable United
;;; States export control laws.
;;;
;;; This software is made available AS IS, and Xerox Corporation makes no
;;; warranty about the software, its performance or its conformity to any
;;; specification.
;;;
;;; Any person obtaining a copy of this software is requested to send their
;;; name and post office or electronic mail address to:
;;; CommonLoops Coordinator
;;; Xerox PARC
;;; 3333 Coyote Hill Rd.
;;; Palo Alto, CA 94304
;;; (or send Arpanet mail to CommonLoops-Coordinator.pa@Xerox.arpa)
;;;
;;; Suggestions, comments and requests for improvements are also welcome.
;;; *************************************************************************
;;;
;;;
(in-package "XCL-USER")
;;; Patch a bug with Lambda-substitution
#+Xerox-Lyric
(defun compiler::meta-call-lambda-substitute (node)
(let* ((fn (compiler::call-fn node))
(var-list (compiler::lambda-required fn))
(spec-effects
(il:for var il:in var-list
il:unless (eq (compiler::variable-scope var) :lexical)
il:collect (compiler::effects-representation var)))
;; Bind *SUBST-OCCURED* just so that META-SUBST-VAR-REF ahs a binding
;; to set even when nobody cares.
(compiler::*subst-occurred* nil))
(il:for var il:in var-list
il:as tail il:on (compiler::call-args node)
il:when
(and (eq (compiler::variable-scope var) :lexical)
(compiler::substitutable-p (car tail) var)
(dolist (compiler::spec-effect spec-effects t)
(when
(not (compiler::null-effects-intersection compiler::spec-effect
(compiler::node-affected (car tail))))
(return nil)))
(dolist (compiler::later-arg (cdr tail) t)
(when (not (compiler::passable (car tail) compiler::later-arg))
(return nil))))
il:do
(setf (compiler::lambda-body fn)
(compiler::meta-substitute (car tail) var
(compiler::lambda-body fn))))
(when (null (compiler::node-meta-p (compiler::lambda-body fn)))
(setf (compiler::node-meta-p fn) nil)
(setq compiler::*made-changes* t))))
;;; Some simple optimizations missing from the compiler.
;; Shift by a constant.
;; Unfortunately, these cause the compiler to generate spurious warning
;; messages about "Unknown function IL:LLSH1 called from ..." It's not often
;; you come across a place where COMPILER-LET is really needed.
#+Xerox-Lyric
(progn
(defvar *ignore-shift-by-constant-optimization* nil
"Marker used for informing the shift-by-constant optimizers that they are in
the shift function, and should not optimize.")
(defun il:lrsh1 (x)
(compiler-let ((*ignore-shift-by-constant-optimization* t))
(il:lrsh x 1)))
(defun il:lrsh8 (x)
(compiler-let ((*ignore-shift-by-constant-optimization* t))
(il:lrsh x 8)))
(defun il:llsh1 (x)
(compiler-let ((*ignore-shift-by-constant-optimization* t))
(il:llsh x 1)))
(defun il:llsh8 (x)
(compiler-let ((*ignore-shift-by-constant-optimization* t))
(il:llsh x 8)))
(defoptimizer il:lrsh il:right-shift-by-constant (x n &environment env)
(if (and (constantp n)
(not *ignore-shift-by-constant-optimization*))
(let ((shift-factor (eval n)))
(cond
((not (numberp shift-factor))
(error "Non-numeric arg to ~S, ~S" 'il:lrsh shift-factor))
((= shift-factor 0)
x)
((< shift-factor 0)
`(il:llsh ,x ,(- shift-factor)))
((< shift-factor 8)
`(il:lrsh (il:lrsh1 ,x) ,(1- shift-factor)))
(t `(il:lrsh (il:lrsh8 ,x) ,(- shift-factor 8)))))
'compiler:pass))
(defoptimizer il:llsh il:left-shift-by-constant (x n &environment env)
(if (and (constantp n)
(not *ignore-shift-by-constant-optimization*))
(let ((shift-factor (eval n)))
(cond
((not (numberp shift-factor))
(error "Non-numeric arg to ~S, ~S" 'il:llsh shift-factor))
((= shift-factor 0)
x)
((< shift-factor 0)
`(il:lrsh ,x ,(- shift-factor)))
((< shift-factor 8)
`(il:llsh (il:llsh1 ,x) ,(1- shift-factor)))
(t `(il:llsh (il:llsh8 ,x) ,(- shift-factor 8)))))
'compiler:pass))
)
;; Simple TYPEP optimiziation
#+Xerox-Lyric
(defoptimizer typep type-t-test (object type)
"Everything is of type T"
(if (and (constantp type) (eq (eval type) t))
`(progn ,object t)
'compiler:pass))
;;; Declare side-effects (actually, lack of side-effects) info for some
;;; internal arithmetic functions. These are needed because the compiler runs
;;; the optimizers before checking the side-effects, so side-effect
;;; declarations on the "real" functions are oft times ignored.
#+Xerox-Lyric
(progn
(il:putprops cl::%+ compiler::side-effects-data (:none . :none))
(il:putprops cl::%- compiler::side-effects-data (:none . :none))
(il:putprops cl::%* compiler::side-effects-data (:none . :none))
(il:putprops cl::%/ compiler::side-effects-data (:none . :none))
(il:putprops cl::%logior compiler::side-effects-data (:none . :none))
(il:putprops cl::%logeqv compiler::side-effects-data (:none . :none))
(il:putprops cl::%= compiler::side-effects-data (:none . :none))
(il:putprops cl::%> compiler::side-effects-data (:none . :none))
(il:putprops cl::%< compiler::side-effects-data (:none . :none))
(il:putprops cl::%>= compiler::side-effects-data (:none . :none))
(il:putprops cl::%<= compiler::side-effects-data (:none . :none))
(il:putprops cl::%/= compiler::side-effects-data (:none . :none))
(il:putprops il:lrsh1 compiler::side-effects-data (:none . :none))
(il:putprops il:lrsh8 compiler::side-effects-data (:none . :none))
(il:putprops il:llsh1 compiler::side-effects-data (:none . :none))
(il:putprops il:llsh8 compiler::side-effects-data (:none . :none))
)
;;; Fix a nit in the compiler
#+Xerox-Lyric
(progn
(il:unadvise 'compile)
(il:advise 'compile ':around '(let (compiler::*input-stream*) (inner)))
)
;;; While no person would generate code like (logor x), macro can (and do).
(defun optimize-logical-op-1-arg (form env ctxt)
(declare (ignore env ctxt))
(if (= 2 (length form))
(second form)
'compiler::pass))
(xcl:defoptimizer logior optimize-logical-op-1-arg)
(xcl:defoptimizer logxor optimize-logical-op-1-arg)
(xcl:defoptimizer logand optimize-logical-op-1-arg)
(xcl:defoptimizer logeqv optimize-logical-op-1-arg)
#+Xerox-Medley
;; A bug compiling LABELS
(defun compiler::meta-call-labels (compiler::node compiler:context)
;; This is similar to META-CALL-LAMBDA, but we have some extra information.
;; There are only required arguments, and we have the correct number of them.
(let ((compiler::*made-changes* nil))
;; First, substitute the functions wherever possible.
(dolist (compiler::fn-pair (compiler::labels-funs compiler::node)
(when (null (compiler::node-meta-p (compiler::labels-body compiler::node)))
(setf (compiler::node-meta-p compiler::node) nil)
(setq compiler::*made-changes* t)))
(when (compiler::substitutable-p (cdr compiler::fn-pair)
(car compiler::fn-pair))
(let ((compiler::*subst-occurred* nil))
;; First try substituting into the body.
(setf (compiler::labels-body compiler::node)
(compiler::meta-substitute (cdr compiler::fn-pair)
(car compiler::fn-pair)
(compiler::labels-body compiler::node)))
(when (not compiler::*subst-occurred*)
;; Wasn't in the body - try the other functions.
(dolist (compiler::target-pair (compiler::labels-funs compiler::node))
(unless (eq compiler::target-pair compiler::fn-pair)
(setf (cdr compiler::target-pair)
(compiler::meta-substitute (cdr compiler::fn-pair)
(car co